home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
8538
/
8538.xpi
/
content
/
boot
/
scripts
/
boot.js
next >
Wrap
Text File
|
2010-02-06
|
16KB
|
555 lines
// This file contains the minimum set of scripts needed to boot Feedly. By boot we mean start, check version, if necessary
// download and expand app and load the application. It is important to keep the boot to the very minimum because
// we can not auto-update the boot.
// ---------------------------------------------------------------------------------------------
// OBSERVABLE
// ---------------------------------------------------------------------------------------------
function createObservable( id )
{
// private variables and methods ----------------------------
var fObservers = []
// public interface -----------------------------------------
var that = {};
that.id = id;
that.registerObserver = function( obsObj )
{
if (fObservers.indexOf(obsObj) >= 0) {
return
}
// BDH: that.$debug( "Registering observer for:" + id + " has " + fObservers.length + " observers. Hint: " + obsObj.id );
fObservers.push(obsObj)
}
that.unregisterObserver = function( obsObj )
{
///D that.$debug( "unregistering observer for:" + that.id + " -- channel: " + getChannelId(obsObj) );
var idx = fObservers.indexOf(obsObj)
if (idx < 0) {
return
}
fObservers.splice(idx,1)
}
that.removeAllObservers = function ()
{
fObservers = []
}
that.fire = function ( aspect,a1,a2,a3,a4,a5,a6,a7,a8 ) // , arg1 , ..., argN
{
// Are there any observers?
if( fObservers.length == 0 ) {
return
}
// copy list of observers, so we don't mutate while we loop
var observers = new Array()
for(var oI in fObservers) {
observers.push ( fObservers [oI] )
}
// The observer list may change as it fire notifications. Make sure that
// we take this into account
// Iterate through list of observers
for( var i=0; i < observers.length; i++ )
{
try
{
// Notify each observer
var obs = observers[i]
if (fObservers.indexOf(obs) < 0) {
continue
}
// 1. check if the aspect is a property of observer
if( obs[aspect] != null )
{
// Call this method; here we don't pass aspect
obs[aspect].call (obs,a1,a2,a3,a4,a5,a6,a7,a8);
continue;
}
// 2. check generic onEvent method
if (obs.onEvent != null)
{
// generic aspect: 'onChanged'
obs.onChanged.call ( obs, aspect,a1,a2,a3,a4,a5,a6,a7,a8 )
continue;
}
// 3. It's a function
if ( typeof( obs ) == "function" )
{
obs.call ( obs, aspect,a1,a2,a3,a4,a5,a6,a7,a8 )
continue;
}
}
catch( e )
{
// ignore
that.$debug( devhd.utils.ExceptionUtils.formatError( "notify observer", e ) + ". Hint about observer:" + observers[ i ].id + "." + aspect );
// that.unregisterObserver( observers[i] );
}
}
// done
};
that.toString = function ()
{
return "[service:" + this.id + "]"
}
that.$debug = function (msg)
{
$debug( "[" + this.id + "] " + msg)
}
return that;
};
function createNetworkStack( id )
{
var HTTP_MAX_TIMEOUT = 60 * 1000; // 60 seconds
var that = createObservable (id)
/////////////////////////////////////////////////
// HTTP/XML COMMUNICATION FACILITIES
/////////////////////////////////////////////////
that.get = function( url, onCompleteFunction, onErrorFunction, contentType )
{
var timeoutTimer = null;
function onCompleteHandler()
{
try
{
///D that.$debug( "get completed:" + request.status )
// has this request already timed out?
if( timeoutTimer == null )
return; // if so there is nothing to be done
// cancel timeout timer
that.clearTimeout( timeoutTimer );
timeoutTimer = null;
if( request.status < 200 || request.status >=300 )
{
onErrorFunction.call( this, request.status, request.statusMessage );
}
else
{
if( contentType == "text/xml" )
{
var responseXML = request.responseXML;
onCompleteFunction.call( this, responseXML );
}
else
{
var responseText = request.responseText;
// try to see if there is a "data-version" header associated with the response
var dataVersion = request.getResponseHeader( "data-version" );
onCompleteFunction.call( this, responseText, dataVersion );
}
}
}
catch( e )
{
that.$debug( "Javascript exception while completing get:" + e.name + " - " + e.message + " -- " + e.fileName + " -- " + e.lineNumber )
onErrorFunction.call( this, -1, "Javascript Exception: " + e.name + " - " + e.message );
}
}
function onErrorHandler()
{
///D that.$debug( "get onErrorHandler:" + url + " -- " + timeoutTimer );
// has this request already timed out?
if( timeoutTimer == null )
return; // if so there is nothing to be done
// cancel timeout timer
that.clearTimeout( timeoutTimer );
timeoutTimer = null;
var stat, statMsg;
try
{
stat = request.status;
statMsg = request.statusMessage;
}
catch( e )
{
stat = -3;
statMsg = "data unavailable";
}
onErrorFunction.call( this, stat, statMsg );
}
try
{
var request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
// QI the object to nsIDOMEventTarget to set event handlers on it:
request.QueryInterface(Components.interfaces.nsIDOMEventTarget);
request.addEventListener( "load", onCompleteHandler, false );
request.addEventListener( "error", onErrorHandler, false );
// QI it to nsIXMLHttpRequest to open and send the request:
request.QueryInterface(Components.interfaces.nsIXMLHttpRequest);
request.open("GET", url, true);
request.send(null);
// set a timeout of 30 seconds
timeoutTimer = that.setTimeout( function()
{
timeoutTimer = null;
onErrorFunction.call( this, -2, "request timedout" );
},
HTTP_MAX_TIMEOUT
);
}
catch( e )
{
that.$debug( "Javascript exception while executing get:" + e.name + " - " + e.message )
onErrorFunction.call( this, -1, "Javascript Exception: " + e.name + " - " + e.message );
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Streets Timer Facility
///////////////////////////////////////////////////////////////////////////////////////////////////
var nextTimerID = 1
var timers = {}
function addTimer ( aTimer, kind )
{
var id = kind + nextTimerID++
timers [ id ] = aTimer
// that.$debug("added " + id)
return id
}
function clearTimer ( id )
{
var t = timers [id]
if (t) {
t.cancel()
delete timers[id]
// that.$debug("cleared " + id)
return true
}
return false
}
var Timer = Components.classes["@mozilla.org/timer;1"];
var nsITimer = Components.interfaces.nsITimer;
that.setTimeout = function( callbackFunc, delay )
{
var aTimer = Timer.createInstance(nsITimer);
var timerId = addTimer(aTimer,"timeout.oneshot.")
aTimer.init( { observe: function() {
clearTimer (timerId)
callbackFunc.call( this );
}
},
delay,
nsITimer.TYPE_ONE_SHOT
);
return timerId;
}
that.clearTimeout = function( id )
{
return clearTimer( id );
}
that.setInterval = function( callbackFunc, delay )
{
var aTimer = Timer.createInstance(nsITimer);
var timerId = addTimer ( aTimer,"interval.slack." )
aTimer.init( { observe: function()
{
callbackFunc.call( this );
} },
delay,
nsITimer.TYPE_REPEATING_SLACK
);
return timerId;
}
that.clearInterval = function( id )
{
return clearTimer( id );
}
that.setCookieString = function( uri, cookieString )
{
var cookieManager = Components.classes["@mozilla.org/cookiemanager;1"]
.getService( Components.interfaces.nsICookieManager );
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var cookieService = Components.classes["@mozilla.org/cookieService;1"]
.getService(Components.interfaces.nsICookieService);
if( ioService == null || cookieManager == null )
return;
var cookieURI = ioService.newURI( uri, null, null);
cookieService.setCookieString( cookieURI, null, cookieString , null);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Content download capabilities
///////////////////////////////////////////////////////////////////////////////////////////////////
/**
* The download listener.
*
* @param {Object} completeFunc
* @param {Object} errorFunc
*/
function Downloader (persist, httpChannel, completeFunc, errorFunc ) {
this.persist = persist
this.persist.progressListener = this
this.httpChannel = httpChannel
this.completeFunc = completeFunc
this.errorFunc = errorFunc;
}
Downloader.prototype = {
saveTo: function ( localURI ) {
this.persist.saveChannel(this.httpChannel,localURI);
},
cancelSave: function () {
this.persist.cancelSave();
},
setTimeoutTimer: function (aTimer) {
this.aTimer = aTimer
},
QueryInterface: function(aIID)
{
if( aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
},
onLocationChange: function (webProgress , request , location )
{
},
onProgressChange: function ( webProgress , request , curSelfProgress , maxSelfProgress, curTotalProgress, maxTotalProgress )
{
},
onSecurityChange: function ( webProgress , request , state )
{
},
onStatusChange: function (webProgress, request, status, message )
{
},
onStateChange: function(aProgress, aRequest, aFlag, aStatus)
{
if(aFlag & Components.interfaces.nsIWebProgressListener.STATE_START)
{
that.$debug("Start download of " + this.httpChannel.URI.spec)
}
else if (aFlag & Components.interfaces.nsIWebProgressListener.STATE_STOP)
{
var majorStatus = 0, status = 0
// if stats != 0, then we don't have http status anyway
if (aStatus == 0) {
status = this.httpChannel.responseStatus
majorStatus = Math.floor(status/100)
}
clearTimer ( this.aTimer );
that.$debug("Finished download of " + this.httpChannel.URI.spec + " [" + status + "," + aStatus.toString(16) + "]")
if ( (majorStatus == 2 || majorStatus == 3) && aStatus == 0) {
if (this.completeFunc) {
that.setTimeout(this.completeFunc,0)
}
} else {
if (this.errorFunc) {
that.setTimeout(this.errorFunc,0);
}
}
}
}
}
/**
* The actual download hook.
* @param {Object} remoteLocation
* @param {Object} localLocation
* @param {Object} onComplete
* @param {Object} onError
*/
that.download = function( remoteLocation, localLocation, onComplete, onError )
{
var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
var persist = Components.classes['@mozilla.org/embedding/browser/nsWebBrowserPersist;1']
.createInstance(Components.interfaces.nsIWebBrowserPersist);
persist.persistFlags = Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION
| Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES
| Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_BYPASS_CACHE ;
var remoteURI = ioService.newURI(remoteLocation, null, null);
var localURI = ioService.newURI(localLocation, null, null);
var channel = ioService.newChannelFromURI( remoteURI );
var downloader = new Downloader ( persist, channel.QueryInterface(Components.interfaces.nsIHttpChannel),
onComplete , onError )
// note: for some reason doing this from inside the callbacks in the
// Downloader does not work - the http channel always aborts !!
downloader.setTimeoutTimer( that.setTimeout(function() { downloader.cancelSave() },HTTP_MAX_TIMEOUT ) )
// start it
downloader.saveTo( localURI )
// this way you can save cancelSave
return downloader;
}
// File helper
var PERMS_DIRECTORY = 0755;
that.getFile = function( path, relativePath )
{
var obj = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
obj.initWithPath( path );
if( relativePath != null )
{
var parts = relativePath.split( "/" );
for( var i = 0; i < parts.length; i++ )
obj.append( parts[ i ] );
}
if( obj.exists() == false )
obj.create( Components.interfaces.nsILocalFile.NORMAL_FILE_TYPE, PERMS_DIRECTORY );
return obj;
}
that.getDir = function( path, relativePath )
{
var obj = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
obj.initWithPath( path );
if( relativePath != null )
{
var parts = relativePath.split( "/" );
for( var i = 0; i < parts.length; i++ )
obj.append( parts[ i ] );
}
if( obj.exists() == false )
obj.create( Components.interfaces.nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY );
return obj;
}
that.removeDir = function( path, relativePath )
{
var obj = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
obj.initWithPath( path );
if( relativePath != null )
{
var parts = relativePath.split( "/" );
for( var i = 0; i < parts.length; i++ )
obj.append( parts[ i ] );
}
if( obj.exists() == true )
obj.remove( true );
}
that.extractZipFile = function( zipFile, targetLocation )
{
///D that.$debug( "received request to extract zip file into: " + targetLocation );
var zipReader = Components.classes["@mozilla.org/libjar/zip-reader;1"]
.createInstance(Components.interfaces.nsIZipReader);
if( zipReader.init != null ) // FF2
{
zipReader.init( zipFile );
zipReader.open();
// create directories first
var entries = zipReader.findEntries("*/");
while (entries.hasMoreElements())
{
var entry = entries.getNext().QueryInterface(Components.interfaces.nsIZipEntry);
// getDir will create the directory if it does not exist
var target = that.getDir( targetLocation, entry.name );
}
entries = zipReader.findEntries( "*" );
while( entries.hasMoreElements() )
{
var entry = entries.getNext().QueryInterface( Components.interfaces.nsIZipEntry );
var entryName = new String( entry.name );
if( entryName.lastIndexOf( "/" ) == entryName.length - 1 )
continue; // skip directories
var targetFile = that.getFile( targetLocation, entry.name );
zipReader.extract(entry.name, targetFile);
}
zipReader.close();
}
else //FF3
{
zipReader.open( zipFile );
// create directories first
var entryNames = zipReader.findEntries("*/");
while (entryNames.hasMore())
{
// getDir will create the directory if it does not exist
var target = that.getDir( targetLocation, entryNames.getNext() );
}
entryNames = zipReader.findEntries( "*" );
while( entryNames.hasMore() )
{
var entryName = entryNames.getNext();
if( entryName.lastIndexOf( "/" ) == entryName.length - 1 )
continue; // skip directories
var targetFile = that.getFile( targetLocation, entryName );
zipReader.extract( entryName, targetFile);
}
zipReader.close();
}
}
//
return that;
}